import { _decorator, Component, Node, Sprite, ImageAsset, SpriteFrame, resources, SpriteAtlas, Texture2D, loader } from 'cc';
import { ResMgr } from '../Managers/ResMgr';
import { AB_Name, Atlas_Name } from '../Data/GameConstant';
const { ccclass, property } = _decorator;

/**
 * 图集工具类
 */
@ccclass('SpriteUtil')
export class SpriteUtil extends Component {
    /**
     * 图集字典
     */
    private _atlasDic:object = {};
    /**
     * 获取图集
     */
    public static Instance:SpriteUtil = null;

    protected onLoad(): void {
        if(null === SpriteUtil.Instance){
            SpriteUtil.Instance = this;
        }else{
            this.destroy();
            return;
        }
    }
    /**
     * 预先加载
     */
    public preload():void{
        this.preloadABAtlas();
    }
    /**
     * 保存atlas
     * @param key 
     * @param atlas 
     */
    private saveAtlasDic(key:string, atlas:SpriteAtlas):void{
        if(null != atlas){
            this._atlasDic[key] = atlas;
            console.log("[SpriteUtil] saveAtlasDic succ key-->" + key);
        }
    }

    /**
     * 预加载图集资源
     * 该方法用于加载GUI相关的图集资源，使用SpriteUtil中定义的棋盘纹理图集
     * 加载完成后会回调onLoadAtlas方法
     */
    private preloadABAtlas():void{
        ResMgr.Instance.loadResBySpriteAtlas(AB_Name.GUI, Atlas_Name.Chess, (asset)=>{
            this.saveAtlasDic(Atlas_Name.Chess, asset);
        });
    }
    
    /**
     * 为 sprite 设置 ab 包图片资源
     * @param sprite 
     * @param abName 
     * @param resName 
     */
    public setAsset(sprite:Sprite, abName:string, resName:string):void{
        var tmpAsset:any = ResMgr.Instance.getAsset(abName, resName);
        if(null != tmpAsset){
            sprite.spriteFrame = SpriteFrame.createWithImage(tmpAsset);
        }
    }

    /**
     * 
     * @param sprite 
     * @param abName 
     * @param resName 
     */
    public setSpriteFrame(sprite:Sprite, abName:string, resName:string):void{
        var bundle = ResMgr.Instance.getBundle(abName);
        if(null != bundle){
            bundle.loadDir(resName, SpriteFrame, (err, spriteFrames)=>{
                if(!err && null != spriteFrames && spriteFrames.length > 0){
                    sprite.spriteFrame = spriteFrames[0];
                }
            });
        }
    }
    /**
     * 
     * @param sprite 
     * @param abName 
     * @param atlasName 
     * @param spriteName 
     * @param fn 
     */
    public setSpriteABAtlas(sprite:Sprite, abName:string, atlasName:string, spriteName:string, fn:Function=null){
        //
        if(!this.setSpriteFrameByAtlas(sprite, atlasName, spriteName)){
            this.setAltasSpriteFrame(sprite, abName, atlasName, spriteName, fn);
        }
    }

    //
    private setSpriteFrameByAtlas(sprite:Sprite, atlasName:string, spriteName:string):SpriteFrame{
        if(this._atlasDic.hasOwnProperty(atlasName)){
            var atlas = this._atlasDic[atlasName];
            var sp:SpriteFrame = atlas.getSpriteFrame(spriteName);
            if(null != sp){
                sprite.spriteFrame = sp;
            }
            return sp;
        }else{
            return null;
        }
    }

    /**
     * 设置棋盘图集
     * @param sprite 
     * @param spriteName 
     * @param fn 
     */
    public setChessAtlasSpriteFrame(sprite:Sprite, spriteName:string, fn:Function = null):void{
        this.setAltasSpriteFrame(sprite, AB_Name.GUI, Atlas_Name.Chess, spriteName, fn);
    }

    /**
     * 设置图集精灵
     * @param sprite 
     * @param abName 
     * @param atlasName 
     * @param spriteName 
     * @param fn 
     */
    public setAltasSpriteFrame(sprite:Sprite, abName:string, atlasName:string, spriteName:string, fn:Function):void{
        var sp:SpriteFrame = this.setSpriteFrameByAtlas(sprite, atlasName, spriteName);
        if(null != sp){
            if(null != fn) fn(sp);
        }
        //
        var bundle = ResMgr.Instance.getBundle(abName);
        if(null != bundle){
            //
            ResMgr.Instance.loadResBySpriteAtlas(abName, atlasName, (atlas:SpriteAtlas)=>{
                if(atlas){
                    //
                    this.saveAtlasDic(atlasName, atlas);
                    //
                    var sp:SpriteFrame = null;
                    if(null != spriteName){
                        sp = atlas.getSpriteFrame(spriteName);
                        if(null != sp) sprite.spriteFrame = sp;
                    }
                    //
                    if(null != fn) fn(atlas, sp);
                }else{
                    if(null != fn) fn(null, null);
                    console.log("atlas is null");
                }
            });
        }else{
            console.log("bundle is null");
            // ResMgr.Instance.loadAssetBundle(abName, ()=>{
            //     if(ResMgr.Instance.getBundle(abName)){
            //         this.setAltasSpriteFrame(sprite, abName, atlasName, spriteName, fn);
            //     }
            // });
        }
    }
    
    /**
     * https://docs.cocos.com/creator/3.1/manual/zh/asset/dynamic-load-resources.html
     * https://docs.cocos.com/creator/2.4/manual/zh/scripting/asset-bundle.html
     * @param sprite 
     * @param resourcePath 
     */
    public setSpriteAtlasInResources(sprite:Sprite, resourcePath){
        resources.load("assets/sheep", SpriteAtlas, (err, atlas)=>{
            if(null == atlas) return;
            var frame = atlas.getSpriteFrame("sheep_down_0");
            sprite.spriteFrame = frame;
        });
    }
}
